package org.mybatis.spring;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.classreading.MetadataReader;

import java.io.IOException;
import java.util.Set;

/**
 * @author LIU
 * @version 1.0
 * @date 2024/1/25 11:23
 * @description TODO
 *  利用spring的扫描逻辑，扫描mapper接口
 *  继承ClassPathBeanDefinitionScanner，修改spring扫描逻辑
 */
public class LiuMapperScanner extends ClassPathBeanDefinitionScanner {

    public LiuMapperScanner(BeanDefinitionRegistry registry) {
        super(registry);
    }

    /**
     * 扫描到mapper接口，修改成LiuFactoryBean生成代理类
     */
    @Override
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        Set<BeanDefinitionHolder> beanDefinitionHolders = super.doScan(basePackages);
        //把扫描到mapper接口，修改成LiuFactoryBean生成代理类
        for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
            GenericBeanDefinition beanDefinition = (GenericBeanDefinition)beanDefinitionHolder.getBeanDefinition();

            // 设置构造函数参数  public LiuFactoryBean(Class mapperClass)
            beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanDefinition.getBeanClassName());
            // 设置类型
            beanDefinition.setBeanClass(LiuFactoryBean.class);
        }

        return beanDefinitionHolders;
    }

    /**
     * 判断是不是一个Bean,默认都是
     */
    @Override
    protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
        return true;
    }
    /**
     *  类必须是一个接口
     */
    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        return beanDefinition.getMetadata().isIndependent();
    }
}
